<?php
/**
 * polwebgis
 * 
 * This file is part of polwebgis.
 *
 * @copyright   Copyright (c) 2012 Dominik Janisch (http://www.joanneum.at)
 * @lastmodified    $LastChangedDate: 2012-03-07 09:15:12 +0000 (Wed, 07 Mar 2012) $
 * @revision    $Revision: 160 $ 
 */
require_once(PATH_TO_APP . "/components/debugger/Debugger.php");
class Layers
{  
    private $map_;
    private $arr_layers_ = array();
    private $arr_layer_properties_ = array();
    private $map_list_;
    private $request_;
    private $e_id_;
    private $projection_;
    //private $debugger_;
    
    const PROPERTY_LAYER_OPACITY = 100;
    
    const PROPERTY_LAYER_FILL_COLOR = '#000000';
    
    const PROPERTY_LAYER_NO_FILLING = true;
    
    const PROPERTY_LAYER_OUTLINE_COLOR = '#000000';
    
    const PROPERTY_LAYER_OUTLINE_WIDTH = 1;
    
    const PROPERTY_LAYER_MAX_OUTLINE_WIDTH = 10;
    
    const LABELING_NO_CHANGE = 'no_change';
    
    const LABELING_SHOW_ALL = 'all';
    
    const LABELING_INTERSECT = 'intersect';
    
    const LABELING_CONTAIN_OVERLAY = 'contain_overlay';
    
    const LABELING_CONTAIN_BASELAYER = 'contain_baselayer';
    
    const LABELING_WITHIN = 'within';

    public function __construct(&$map, &$map_list, $request, $add_layers, $e_id, $projecction)
    {
        //$this->debugger_ = new Debugger();
        $this->map_ = $map;
        $this->e_id_ = $e_id;
        $this->projection_ = $projecction;
        $this->map_list_ = $map_list;
        $this->request_ = $request;
        if($this->map_list_->get('arr_layers') != false)
            $this->arr_layers_ = $this->map_list_->get('arr_layers');
        if($this->map_list_->get('arr_layer_properties') != false)
            $this->arr_layer_properties_ = $this->map_list_->get('arr_layer_properties');
        if(count($this->request_->getArray('post')) > 0)
            $this->checkInput();
        $this->map_list_->set('arr_layers', $this->arr_layers_);
        $this->map_list_->set('arr_layer_properties', $this->arr_layer_properties_);
        if($add_layers)
            $this->addLayers();
    }
        
    public function __destruct(){}
    
    public function assignPropertiesToTemplate($output_handler, $layer)
    {
        $arr_layer_params = explode('|', $layer);
        /*if(count($arr_layer_params) != 2)
            return false;*/
        if(!array_key_exists($arr_layer_params[0], $this->arr_layer_properties_))
            $this->setLayer($arr_layer_params[0], $arr_layer_params[1]);
        $database_connection = new LayersGateway();
        $is_shape = strpos($arr_layer_params[0] , 'shape') !== false ? true : false;
        $arr_regions = $database_connection->getRegions($arr_layer_params[0], $is_shape);
        $arr_properties = $this->getLayer($arr_layer_params[0]);
        $output_handler->assignValuesToTemplate(array("arr_properties" => $arr_properties, "arr_regions" => $arr_regions, "regionscount" => count($arr_properties['areas'])));
        
    }
    
    private function checkInput()
    {
        if($this->request_->issetParameter('get', 'overlayupdate'))
        {
            $arr_layer_params = explode('|', $this->request_->getParameter('get', 'overlay'));
            $layer = $arr_layer_params[0]; 
            if($this->request_->issetParameter('post', 'layer_opacity'))
            {
                $layer_opacity = (int)$this->request_->getParameter('post', 'layer_opacity')>=0 && (int)$this->request_->getParameter('post', 'layer_opacity')<=constant("self::PROPERTY_LAYER_OPACITY") ? (int)$this->request_->getParameter('post', 'layer_opacity') : constant("self::PROPERTY_LAYER_OPACITY");
                $this->setLayerProperty($layer, 'layer_opacity', $layer_opacity);
            }
            if($this->request_->issetParameter('post', 'fill_color'))
            {
                $fill_color = $this->extractColor($this->request_->getParameter('post', 'fill_color'));
                if($fill_color !== false)
                    $this->setLayerProperty($layer, 'fill_color', $fill_color);
            }
            if($this->request_->issetParameter('post', 'no_filling'))
            {
                $this->setLayerProperty($layer, 'no_filling', true);
            }
            else
            {
                $this->setLayerProperty($layer, 'no_filling', false);
            }
            if($this->request_->issetParameter('post', 'outline_color'))
            {
                $outline_color = $this->extractColor($this->request_->getParameter('post', 'outline_color'));
                if($outline_color !== false)
                    $this->setLayerProperty($layer, 'outline_color', $outline_color);
            }
            if($this->request_->issetParameter('post', 'outline_width'))
            {
                $outline_width = (int)$this->request_->getParameter('post', 'outline_width')>=1 && (int)$this->request_->getParameter('post', 'outline_width')<=constant("self::PROPERTY_LAYER_MAX_OUTLINE_WIDTH") ? (int)$this->request_->getParameter('post', 'outline_width') : constant("self::PROPERTY_LAYER_OUTLINE_WIDTH");
                $this->setLayerProperty($layer, 'outline_width', $outline_width);
            }
            if($this->request_->issetParameter('post', 'arr_regions'))
            {
                $arr_tmp = array();
                foreach($this->request_->getParameter('post', 'arr_regions') as $item)
                {
                    $arr_tmp[$item] = $item;
                }
                $this->setLayerProperty($layer, 'areas', $arr_tmp);
            }
            if($this->request_->issetParameter('post', 'baselayer_labeling'))
            {
                switch($this->request_->getParameter('post', 'baselayer_labeling'))
                {
                    case constant("self::LABELING_INTERSECT"):
                        $database_connection = new LayersGateway();
                        $this->map_list_->set('arr_layer_gids', $database_connection->getIntersectRegions($this->e_id_, $layer, $this->getLayerProperty($layer, 'areas')));
                        $this->setLayerProperty($layer, 'baselayer_labeling', constant("self::LABELING_INTERSECT"));
                        break;
                    case constant("self::LABELING_CONTAIN_OVERLAY"):
                        $database_connection = new LayersGateway();
                        $this->map_list_->set('arr_layer_gids', $database_connection->getContainedOverlayRegions($this->e_id_, $layer, $this->getLayerProperty($layer, 'areas')));
                        $this->setLayerProperty($layer, 'baselayer_labeling', constant("self::LABELING_CONTAIN_OVERLAY"));
                        break;
                    case constant("self::LABELING_CONTAIN_BASELAYER"):
                        $database_connection = new LayersGateway();
                        $this->map_list_->set('arr_layer_gids', $database_connection->getContainedBaseLayerRegions($this->e_id_, $layer, $this->getLayerProperty($layer, 'areas')));
                        $this->setLayerProperty($layer, 'baselayer_labeling', constant("self::LABELING_CONTAIN_BASELAYER"));
                        break;
                    case constant("self::LABELING_WITHIN"):
                        $distance = (float)$this->request_->getParameter('post', 'within_distance');
                        $database_connection = new LayersGateway();
                        $this->map_list_->set('arr_layer_gids', $database_connection->getWithinRegions($this->e_id_, $layer, $distance, $this->getLayerProperty($layer, 'areas')));
                        $this->setLayerProperty($layer, 'baselayer_labeling', constant("self::LABELING_CONTAIN_BASELAYER"));
                        $this->setLayerProperty($layer, 'within_distance', $distance);
                        break;
                    case constant("LABELING_SHOW_ALL"):
                        $this->map_list_->set('arr_layer_gids', null);
                        $this->setLayerProperty($layer, 'baselayer_labeling', constant("self::LABELING_SHOW_ALL"));
                        break;
                    default:
                        $this->setLayerProperty($layer, 'baselayer_labeling', constant("self::LABELING_NO_CHANGE"));
                }
            }
        }
        else
        {
            if($this->request_->issetParameter('post', 'refreshmap'))
            {
                $this->arr_layers_ = array();
                if($this->request_->issetParameter('post', 'arr_layers'))
                {
                    foreach(array_reverse($this->request_->getParameter('post', 'arr_layers')) as $item)
                    {
                        $arr_layer_params = explode('|', $item);
                        if(count($arr_layer_params) == 2)
                        {
                            $this->arr_layers_[$arr_layer_params[0]] = $arr_layer_params[0];
                            $this->setLayer($arr_layer_params[0], $arr_layer_params[1]);
                        }
                    }
                }
            }
        }
    }
    
    private function extractColor($color)
    {
        $tmp_color = preg_replace("/[^0-9A-Fa-f]/", '', $color);
        if(strlen($tmp_color) == 6)
            return $tmp_color;
        return false;
    }
    
    private function setLayerProperty($layer, $property, $value)
    {
        if(!array_key_exists($layer, $this->arr_layer_properties_))
            $this->setLayer($layer);
        if(array_key_exists($property, $this->arr_layer_properties_[$layer]))
            $this->arr_layer_properties_[$layer][$property] = $value;
    }
    
    private function getLayerProperty($layer, $property)
    {
        if(array_key_exists($property, $this->arr_layer_properties_[$layer]))
            return $this->arr_layer_properties_[$layer][$property];
        return false;
    }
    
    private function getLayer($layer)
    {
        return $this->arr_layer_properties_[$layer];
        
    }
    
    private function setLayer($layer, $name)
    {
        if(!array_key_exists($layer, $this->arr_layer_properties_))
        {
            $this->arr_layer_properties_[$layer]['layer_opacity'] = constant("self::PROPERTY_LAYER_OPACITY");
            $this->arr_layer_properties_[$layer]['fill_color'] = constant("self::PROPERTY_LAYER_FILL_COLOR");
            $this->arr_layer_properties_[$layer]['no_filling'] = constant("self::PROPERTY_LAYER_NO_FILLING");
            $this->arr_layer_properties_[$layer]['outline_color'] = constant("self::PROPERTY_LAYER_OUTLINE_COLOR");
            $this->arr_layer_properties_[$layer]['outline_width'] = constant("self::PROPERTY_LAYER_OUTLINE_WIDTH");
            $this->arr_layer_properties_[$layer]['baselayer_labeling'] = constant("self::LABELING_NO_CHANGE");
            $this->arr_layer_properties_[$layer]['within_distance'] = 0;
            $this->arr_layer_properties_[$layer]['areas'] = array();
            $this->arr_layer_properties_[$layer]['name'] = $name;
        }
    }
    
    private function addLayers()
    {
        foreach($this->arr_layers_ as $layer)
        {
            $new_layer = ms_newLayerObj($this->map_);
            $new_layer->set('type', MS_LAYER_POLYGON);
            $new_layer->setConnectionType(MS_POSTGIS);
            $new_layer->set('connection', MAPSERVER_CONNECTION_STRING);
            if(count($this->arr_layer_properties_[$layer]['areas']) == 0)
            {
                $new_layer->set('data', 'the_geom from '.$layer);
            }
            else
            {
                if(strpos($layer , 'shape') !== false)
                {
                    $new_layer->set('data', "the_geom from (select the_geom, gid, region from ".$layer." where gid IN (".implode(',', $this->arr_layer_properties_[$layer]['areas']).")) as tmp using unique gid using SRID=".$this->projection_);
                }
                else
                {
                    $new_layer->set('data', "the_geom from (select the_geom, gid, overlay_name from ".$layer." where gid IN (".implode(',', $this->arr_layer_properties_[$layer]['areas']).")) as tmp using unique gid using SRID=".$this->projection_);
                }
            }
            $new_layer->set('status', MS_ON);
            $new_layer->set('name', $layer);
            $new_layer->set('opacity', $this->arr_layer_properties_[$layer]['layer_opacity']);
            $class_obj = ms_newClassObj($new_layer);
            $class_obj->set('name', $this->arr_layer_properties_[$layer]['name']);
            if(!$this->arr_layer_properties_[$layer]['no_filling'])
            {
                $fill_style = ms_newStyleObj($class_obj);
                $fill_style->color->setRGB(hexdec(substr($this->arr_layer_properties_[$layer]['fill_color'], 0, 2)), hexdec(substr($this->arr_layer_properties_[$layer]['fill_color'], 2, 2)), hexdec(substr($this->arr_layer_properties_[$layer]['fill_color'], 4, 2)));  
            }
            $style = ms_newStyleObj($class_obj);
            $style->set('width', $this->arr_layer_properties_[$layer]['outline_width']);
            $style->set('antialias', true);
            $style->outlinecolor->setRGB(hexdec(substr($this->arr_layer_properties_[$layer]['outline_color'], 0, 2)), hexdec(substr($this->arr_layer_properties_[$layer]['outline_color'], 2, 2)), hexdec(substr($this->arr_layer_properties_[$layer]['outline_color'], 4, 2)));
        }
    }
}

?>
